import 'dart:async';
import 'package:flutter/material.dart';
import 'package:avd_sdk_plugin/rtc_video_render.dart';
import 'package:avd_sdk_plugin/avd_sdk_plugin.dart';
import 'package:avd_sdk_plugin/avd_message.dart';

class MeetingDisplay extends StatefulWidget {
  /// non-modifiable channel name of the page
  final String channelName = '';

  @override
  _MeetingDisplayState createState() => _MeetingDisplayState();
}

class _MeetingDisplayState extends State<MeetingDisplay> {
  final _users = <String>[];
  final _infoStrings = <String>[];
  bool muted = false;
  bool isClose = false;
  bool isSpeaker = false;
  final listRender = <RTCVideoRender>[];

  @override
  void dispose() {
    // clear users
    _users.clear();
    // destroy sdk
    listRender.clear();
    _infoStrings.clear();
    AvdSdkPlugin.leaveRoom();
    print('MeetingDisplay dispose');
    super.dispose();


  }

  @override
  void initState() {
    super.initState();
    // _users.add('22');
    // _users.add('33');
    // _users.add('44');
    // _users.add('55');
    RTCVideoRender render1 =  RTCVideoRender(tagId:'localUser');
    RTCVideoRender render2 =  RTCVideoRender(tagId:'remoteUser1');
    RTCVideoRender render3 =  RTCVideoRender(tagId:'remoteUser2');
    RTCVideoRender render4 =  RTCVideoRender(tagId:'remoteUser3');
    listRender.add(render1);
    listRender.add(render2);
    listRender.add(render3);
    listRender.add(render4);
    initialize();
  }

  Future<void> initialize() async {
      //AvdSdkPlugin.setLogParams('info', 'testPath');
      AvdSdkPlugin.publishCamera();
      AvdSdkPlugin.onPublishLocalResult = (String deviceid){
        print('onPublishLocalResult = $deviceid');
       //获取界面上任意一个没有视频的render
        RTCVideoRender render =  getFreeRender(deviceid);
        //自己的视频不需要订阅操作
        AvdSdkPlugin.attachRenderWithDeviceId(deviceid, render);
      };

      AvdSdkPlugin.onUnpublishLocalResult = (String deviceid){
        //获取界面上对应显示视频的render
        RTCVideoRender render =  getRender(deviceid);
        //自己的视频不需要取消订阅
        AvdSdkPlugin.detachRenderWithDeviceId(deviceid, render);
      };

      AvdSdkPlugin.onPublishCameraNotify = (String deviceid){

        RTCVideoRender render =  getFreeRender(deviceid);
        //先订阅在渲染
        AvdSdkPlugin.subscribe(deviceid);
        AvdSdkPlugin.attachRenderWithDeviceId(deviceid, render);
      };
      AvdSdkPlugin.onUnpublishCameraNotify = (String deviceid){
        //先取消订阅在取消渲染
        RTCVideoRender render =  getRender(deviceid);
        AvdSdkPlugin.unsubscribe(deviceid);
        AvdSdkPlugin.detachRenderWithDeviceId(deviceid, render);
      };

      AvdSdkPlugin.onPublicMessage = (AVDMessage msg){
        String str = msg.message!;
        print('接受到公聊消息 = $str');
      };

  }

  getFreeRender(String did) {
   for(RTCVideoRender render in listRender){
     if(render.deviceid == null){
       render.deviceid = did;
       return render;
     }
   }
  }

  getRender(String did) {
    for(RTCVideoRender render in listRender){
      if(render.deviceid == did){
        render.deviceid = null;
        return render;
      }
    }
  }



  /// Helper function to get list of native views
  List<Widget> _getRenderViews() {
    //_users.forEach((String uid) => list.add(RTCVideoRender()));
    return listRender;
  }

  /// Video view wrapper
  Widget _videoView(view) {
    return Expanded(child: Container(child: view));
  }

  /// Video view row wrapper
  Widget _expandedVideoRow(List<Widget> views) {
    final wrappedViews = views.map<Widget>(_videoView).toList();
    return Expanded(
      child: Row(
        children: wrappedViews,
      ),
    );
  }

  /// Video layout wrapper
  Widget _viewRows() {
    final views = _getRenderViews();
    switch (views.length) {
      case 1:
        return Container(
            child: Column(
              children: <Widget>[_videoView(views[0])],
            ));
      case 2:
        return Container(
            child: Column(
              children: <Widget>[
                _expandedVideoRow([views[0]]),
                _expandedVideoRow([views[1]])
              ],
            ));
      case 3:
        return Container(
            child: Column(
              children: <Widget>[
                _expandedVideoRow(views.sublist(0, 2)),
                _expandedVideoRow(views.sublist(2, 3))
              ],
            ));
      case 4:
        return Container(
            child: Column(
              children: <Widget>[
                _expandedVideoRow(views.sublist(0, 2)),
                _expandedVideoRow(views.sublist(2, 4))
              ],
            ));
      default:
    }
    return Container();
  }

  /// Toolbar layout
  Widget _toolbar() {
    return Container(
      alignment: Alignment.bottomCenter,
      padding: const EdgeInsets.symmetric(vertical: 30),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          SizedBox(
            width: 40,
            child: RawMaterialButton(
              onPressed: _onToggleMute,
              child: Icon(
                muted ? Icons.mic_off : Icons.mic,
                color: muted ? Colors.white : Colors.blueAccent,
                size: 30.0,
              ),
              shape: CircleBorder(),
              elevation: 2.0,
              fillColor: muted ? Colors.blueAccent : Colors.white,
              padding: const EdgeInsets.all(5.0),
            ),
          ),
          SizedBox(
              width: 40,
              child:RawMaterialButton(
                onPressed: _onCameraClicked,
                child: Icon(
                  isClose ? Icons.videocam_off : Icons.videocam,
                  color: isClose ? Colors.white : Colors.blueAccent,
                  size: 30.0,
                ),
                shape: CircleBorder(),
                elevation: 2.0,
                fillColor: isClose ? Colors.blueAccent : Colors.white,
                //padding: const EdgeInsets.all(8.0),
              ),
          ),
          SizedBox(
              width: 70,
              child:RawMaterialButton(
                onPressed: () => _onCallEnd(context),
                child: Icon(
                  Icons.call_end,
                  color: Colors.white,
                  size: 50,
                ),
                shape: CircleBorder(),
                elevation: 2.0,
                fillColor: Colors.redAccent,
                //padding: const EdgeInsets.all(8.0),
              ),
          ),
          SizedBox(
              width: 40,
              child:RawMaterialButton(
                onPressed: _onSwitchCamera,
                child: Icon(
                  Icons.switch_camera,
                  color: Colors.blueAccent,
                  size: 30.0,
                ),
                shape: CircleBorder(),
                elevation: 2.0,
                fillColor: Colors.white,
                //padding: const EdgeInsets.all(8.0),
              ),
          ),
          SizedBox(
              width: 40,
              child:RawMaterialButton(
                onPressed: _onSetSpeakerMode,
                child: Icon(
                  isSpeaker ? Icons.headset_off : Icons.headset,
                  color: isSpeaker ? Colors.white : Colors.blueAccent,
                  size: 30.0,
                ),
                shape: CircleBorder(),
                elevation: 2.0,
                fillColor: Colors.white,
                //padding: const EdgeInsets.all(8.0),
              ),
          ),
        ],
      ),
    );
  }

  /// Info panel to show logs
  Widget _panel() {
    return Container(
      padding: const EdgeInsets.symmetric(vertical: 48),
      alignment: Alignment.bottomCenter,
      child: FractionallySizedBox(
        heightFactor: 0.5,
        child: Container(
          padding: const EdgeInsets.symmetric(vertical: 48),
          child: ListView.builder(
            reverse: true,
            itemCount: _infoStrings.length,
            itemBuilder: (BuildContext context, int index) {
              if (_infoStrings.isEmpty) {
                return Text("null");  // return type can't be null, a widget was required
              }
              return Padding(
                padding: const EdgeInsets.symmetric(
                  vertical: 3,
                  horizontal: 10,
                ),
                child: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Flexible(
                      child: Container(
                        padding: const EdgeInsets.symmetric(
                          vertical: 2,
                          horizontal: 5,
                        ),
                        decoration: BoxDecoration(
                          color: Colors.yellowAccent,
                          borderRadius: BorderRadius.circular(5),
                        ),
                        child: Text(
                          _infoStrings[index],
                          style: TextStyle(color: Colors.blueGrey),
                        ),
                      ),
                    )
                  ],
                ),
              );
            },
          ),
        ),
      ),
    );
  }

  void _onCallEnd(BuildContext context) {

    Navigator.pop(context);
  }

  void _onToggleMute() {
    muted ? AvdSdkPlugin.openMicrophone() : AvdSdkPlugin.closeMicrophone();
    setState(() {
      muted = !muted;
    });

  }

  void _onCameraClicked(){
    isClose ? AvdSdkPlugin.publishCamera() : AvdSdkPlugin.unpublishCamera();
    //isClose ? AvdSdkPlugin.publishScreen() : AvdSdkPlugin.unpublishScreen();
    setState(() {
      isClose = !isClose;
    });

  }


  void _onSwitchCamera() {
     AvdSdkPlugin.switchCamera();
  }

  void _onSetSpeakerMode(){
    isSpeaker?AvdSdkPlugin.setSpeakerMode(1):AvdSdkPlugin.setSpeakerMode(0);
    setState(() {
       isSpeaker  = !isSpeaker;
    });
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('AVDRTC Flutter QuickStart'),
      ),
      backgroundColor: Colors.black,
      body: Center(
        child: Stack(
          children: <Widget>[
            _viewRows(),
            _panel(),
            _toolbar(),
          ],
        ),
      ),
    );
  }
}
